package cn.zwx.dubbo.exception.filter;

import cn.zwx.base.entity.ResponseEntity;
import cn.zwx.base.enums.ResponseCodeEnum;
import cn.zwx.base.exception.BizWrapException;
import cn.zwx.base.utils.json.JsonUtils;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.service.GenericService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;


import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;

/**
 * @author zhangwenxue
 * <code>
 *     最后执行
 * </code>
 */
@Activate(group = {PROVIDER})
public class CustomExceptionFilter implements Filter {

    public static final Logger logger = LoggerFactory.getLogger(CustomExceptionFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Result result = invoker.invoke(invocation);
        if (result.hasException() && invoker.getInterface() != GenericService.class) {
            Throwable exception = result.getException();
            logger.error("invoker:interfaceClass:{}#{},请求参数：{}",invoker.getInterface(),invocation.getMethodName(),
                    JsonUtils.toJsonString(invocation.getArguments()),exception);
            result.setException(null);
            if (exception instanceof BizWrapException) {
                //从而将我们自己定义的异常封装成我们自己的响应对象给到前端。
                result.setValue(ResponseEntity.fail(((BizWrapException) exception).getCode(),((BizWrapException) exception).getMsg()));
            }else if (exception instanceof BindException){
                result.setValue(ResponseEntity.fail(ResponseCodeEnum.PARAMS_VALID_ERROR.getCode(),exception.getMessage()));
            }else  {
                //其他非自定义异常这里可以再包装，道理是一样的
                result.setValue(ResponseEntity.fail(ResponseCodeEnum.RPC_ERROR.getCode(),exception.getMessage()));
            }
            return result;
        }
        return result;
    }

}
